from django.shortcuts import HttpResponse

from app01 import models


def add_book(request):
    """
    添加
    """

    # 方式一：模型类实例化对象
    # book = models.Book(title="菜鸟教程", price=300, publish="菜鸟出版社", pub_date="2008-8-8")
    # book.save()

    # 方式二：通过 ORM 提供的 objects 提供的方法 create 来实现（推荐☆☆☆☆☆）
    book = models.Book.objects.create(title="如来神掌", price=200, publish="功夫出版社", pub_date="2010-10-10")

    print(book, type(book))  # Book object (18)
    return HttpResponse("<p>数据添加成功！</p>")


def find_book(request):
    """
    查找
    """

    # 查询所有数据
    # books = models.Book.objects.all()

    # 查询所有符合条件的数据
    # books = models.Book.objects.filter(publish='菜鸟出版社', price=300)

    # 查询所有不符合条件的数据
    # books = models.Book.objects.exclude(pk=5)

    # 查询结果排序
    # books = models.Book.objects.order_by("price")  # 查询所有，按照价格升序排列
    # books = models.Book.objects.order_by("-price").reverse()  # 查询所有，按照价格降序排列，再反转

    # 查询单个对象，如果符合条件的对象超过了一个或者没有都会抛出错误
    # book = models.Book.objects.get(pk=1)
    # book = models.Book.objects.get(pk=18)  # 报错，没有符合条件的对象
    # book = models.Book.objects.get(price=200)  # 报错，符合条件的对象超过一个

    # 统计数量
    # count = models.Book.objects.count()  # 查询所有数据的数量
    # count = models.Book.objects.filter(price=900).count()  # 查询符合条件数据的数量
    # print(count)

    # books = models.Book.objects.first()  # 返回所有数据的第一条数据，同books[0]
    # books = models.Book.objects.last()  # 返回所有数据的最后一条数据

    # 判断查询结果 QuerySet 列表里是否有数据。
    # books = models.Book.objects.exists()

    # 查询部分字段：查询所有的id字段和price字段的数据
    # 返回的是 QuerySet 类型数据，里面是一个可迭代的字典序列，字典里的键是字段，值是数据
    # books = models.Book.objects.values("pk", "price")
    # print(books[0]["price"], type(books))  # 得到的是第一条记录的price字段的数据

    # 查询所有的price字段和publish字段的数据
    # 返回的是QuerySet类型数据，里面是一个个元组，元组里放的是查询字段对应的数据
    # books = models.Book.objects.values_list("price", "publish")
    # print(books[0][0], type(books))  # 得到的是第一条记录的price字段的数据

    # 对数据进行去重：查询一共有多少个出版社
    # books = models.Book.objects.values_list("publish").distinct()
    # books = models.Book.objects.distinct()  # 对模型类的对象去重没意义，因为每个对象都是不一样的存在。

    """
    filter()方法基于双下划线的模糊查询（exclude同理）。
    filter 中运算符号只能使用等于号 = ，不能使用大于号 > ，小于号 < ，等等其他符号。
    """

    # 查询价格为200或者300的数据
    books = models.Book.objects.filter(price__in=[200, 300])  # __in 用于读取区间，= 号后面为列表
    # 查询价格大于200的数据
    books = models.Book.objects.filter(price__gt=200)  # __gt 大于号 ，= 号后面为数字。（__lt小于）
    # 查询价格大于等于200的数据
    books = models.Book.objects.filter(price__gte=200)  # __gte 大于等于，= 号后面为数字。（__lte小于等于）
    # __range 在...之间，左闭右闭区间，= 号后面为两个元素的列表。
    books = models.Book.objects.filter(price__range=[200, 300])
    # __contains 包含，= 号后面为字符串。
    books = models.Book.objects.filter(title__contains="菜")
    # __icontains 不区分大小写的包含，= 号后面为字符串。
    books = models.Book.objects.filter(title__icontains="python")  # 不区分大小写
    # __startswith 以指定字符开头，= 号后面为字符串。
    books = models.Book.objects.filter(title__startswith="菜")
    # __endswith 以指定字符结尾，= 号后面为字符串。
    books = models.Book.objects.filter(title__endswith="教程")
    # __year 是 DateField 数据类型的年份，= 号后面为数字。（__month、__day）
    books = models.Book.objects.filter(pub_date__year=2008)

    # print(books, type(books))  # QuerySet类型，类似于list。
    for book in books:
        print(book.id, book.title, book.price, book.publish, book.pub_date)

    return HttpResponse("<p>查找成功！</p>")


def del_book(request):
    """
    删除

    注意：
    1. Django 删除数据时，会模仿 SQL约束 ON DELETE CASCADE 的行为，
        也就是删除一个对象时也会删除与它相关联的外键对象。
    2. delete() 方法是 QuerySet 数据类型的方法，但并不适用于 Manager 本身。
        也就是想要删除所有数据，不能不写 all。
    """

    # 方式一：使用模型类的对象.delete()。
    # 返回值：元组，第一个元素为受影响的行数。
    # books = models.Book.objects.filter(pk=8).first().delete()

    # 方式二：使用QuerySet类型数据.delete()(推荐☆☆☆☆☆)
    # 返回值：元组，第一个元素为受影响的行数。
    books = models.Book.objects.filter(pk__in=[3, 4]).delete()
    books = models.Book.objects.all().delete()  # 删除成功
    # books = models.Book.objects.delete()  # 报错

    return HttpResponse("<p>删除成功！</p>")


def upd_book(request):
    """
    修改
    """

    # 方式一：
    #   模型类的对象.属性 = 更改的属性值
    #   模型类的对象.save()
    # 返回值：编辑的模型类的对象。
    books = models.Book.objects.filter(pk=1).first()
    books.price = 400
    books.save()

    # 方式二：
    #   QuerySet类型数据.update(字段名=更改的数据)（推荐☆☆☆☆☆）
    # 返回值：整数，受影响的行数
    books = models.Book.objects.filter(pk__in=[1, 2]).update(price=888)
    return HttpResponse(books)
